#!/bin/python3
# -*- coding: UTF-8
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.colors
import matplotlib.dates as mdates
from matplotlib.ticker import ScalarFormatter
from matplotlib.ticker import LogFormatter
from matplotlib.ticker import MultipleLocator
from matplotlib.ticker import FormatStrFormatter
from matplotlib.font_manager import findfont, FontProperties  
import matplotlib.font_manager as font_manager
from matplotlib.ticker import MaxNLocator
import seaborn as sns

# sns.set_theme()
sns.set_theme(style="ticks", font_scale=1.33)
sns.set_context("paper", font_scale=1.5)
plt.rcParams['xtick.direction'] = 'in'#将x的刻度线方向设置向内
plt.rcParams['ytick.direction'] = 'in'#将y的刻度方向设置向内
plt.rcParams['font.family']=['Sarasa Mono SC'] #用来正常显示中文标签
txt_thread_nr = "线程数"
txt_mops = "吞吐率(Mop/s)"

# 常量颜色
cl_blk = (7/255,7/255,7/255,1)
cl_red = (255/255,59/255,59/255,1)
cl_orange = (255/255,160/255,122/255, 1)

use_libs = ['sffwd', 'flat', 'ccsync', 'dsmsync', 'hsync', 'rcl', 'ffwd', 'cacsffwd', 'cacflat', 'cacccsyn', 'cacdsmsyn', 'cachsyn']

# non_caclocks = ['fc', 'ccsynch', 'dsmsynch', 'hsynch', 'sffwd']
# cac_locks = ['cac_fc', 'cac_ccsynch', 'cac_dsmsynch', 'cac_hsynch', 'cacsffwd']

# 8个小核 16个大核
x86_bigthread_line = '8'
arm_bigthread_line = '4'

x86_hardware_threads = '24'
arm_hardware_threads = '8'


markers=[
	# ".", #atm_add
	# "o", #posix
	# "s", #ticket
	# "x", #spin
	# "v", #clh
	# "^", #mcs
	">", #sffwd
	"o", #fc
	"v", #ccsynch
	"^", #dsmsynch
	"+", #hsynch

	"x", #rcl
	"d", #ffwd

	">", #cac_sffwd
	"o", #cacfc
	"v", #cacccsynch
	"^", #cacdsmsynch
	"+", #cachsynch
	]
colors=[
	cl_blk, #sffwd
	cl_blk, #fc
	cl_blk, #ccsynch
	cl_blk, #dsmsynch
	cl_blk, #hsynch

	cl_orange, #rcl
	cl_orange, #ffwd

	cl_red, #cacsffwd
	cl_red, #cacfc
	cl_red, #cacccsynch
	cl_red, #cacdsmsynch
	cl_red, #cachsynch
]

fst=[
	# "full", #atm_add
	# "full", #posix
	# "full", #ticket
	# "full", #spin
	# "full", #clh
	# "full", #mcs
	"none", #sffwd
	"none", #fc
	"none", #ccsynch
	"none", #dsmsynch
	"none", #hsynch

	"none", #rcl
	"none", #ffwd

	"none", #cacfc
	"none", #cacccsynch
	"none", #cacdsmsynch
	"none", #cachsynch
	"none", #cacsffwd
]

from scipy.stats.mstats import gmean
import sys


def calculate_geomean(datay):
	print (datay)
	ret = gmean(datay)
	print (ret)
	return ret

# 读文件
def read_data(file_path):
	data = np.loadtxt(file_path,dtype=str,delimiter=' ')
	return data

def choose(data, x, col):
	return data[data[:, col] == x, 0:]

def filter(data, x):
	return data[data[:, 0] == x, 1:]

def uniqx(data):
	return np.unique(data[:, 0])

def avg(data):
	# 获得所有lib名字(除去第一行)
	libname = uniqx(data[1:])
	# 获得所有bench 名字
	benchname = uniqx(filter(data, libname[0]))
	# 获得所有的thread
	threadlist = uniqx(filter(filter(data, libname[0]), benchname[0])).astype(int)
	threadlist.sort()
	threadlist = threadlist.astype(str)

	# 计算n次执行结果的平均值和标准差
	avg_result = []
	for lib in libname:
		for bench in benchname:
			for thread in threadlist:
				# 多次执行结果 计算平均值和标准差
				result_data = filter(filter(filter(data, lib), bench), thread).astype(float)
				avg_result.append(np.array([lib, bench, thread, np.mean(result_data).astype(str), np.std(result_data).astype(str)]))
				# print("%s %s %s %.3f %.3f" % (lib, bench, thread, np.mean(result_data), np.std(result_data)))
	avg_result = np.array(avg_result)
	return avg_result, libname, benchname, threadlist

x86filename = sys.argv[1]
armfilename = sys.argv[2]

x86data = read_data(x86filename)
armdata = read_data(armfilename)
x86_avg, x86_libname, x86_benchname, x86_threadlist = avg(x86data)
arm_avg, arm_libname, arm_benchname, arm_threadlist = avg(armdata)

# 画图
def draw_subfig_mop(avg_data, bench_name, thread_list, axs, hardthreads_line, bigthread_line, xlabel, ylabel):
	# 获得该bench的数据后,根据lock信息
	xticks = thread_list
	print (xticks)

	i = 0
	for lib in use_libs:
		# 取得数据
		lib_avg = choose(choose(avg_data, lib, 0), bench_name, 1)
		y =  lib_avg[:, 3].astype(float)
		err = lib_avg[:, 4].astype(float)
		print(y)
		axs.plot(xticks, y, color=colors[i%len(use_libs)], fillstyle = fst[i%len(use_libs)], label=lib, marker=markers[i%len(use_libs)], markersize = 6)
		# 误差棒影响可读性
		# axs.errorbar(xticks, y, yerr = err,  ecolor=colors[i%len(use_libs)], fmt=".k", 
		# marker = " ",
		# alpha = 0.667, elinewidth=1, capsize=2)

		i+=1
	axs.set_xticklabels(xticks)
	axs.set_xlabel(xlabel)
	axs.set_ylabel(ylabel)
	axs.set_ylim(0)
	axs.yaxis.set_major_locator(MaxNLocator(integer=True))
	# axs.set_yscale("log")
	# 计算本次的差距
	# axs.yaxis.set_major_formatter(ScalarFormatter())
	# axs.yaxis.set_major_formatter(LogFormatter)
	# print (axs.get_ylim())
	# axs.set_yticks([1, 2.5, 5, 7.5, 10, (round(axs.get_ylim()[1], -1) - 10) / 2 + 10, round(axs.get_ylim()[1], -1)] )
	# axs.get_yaxis().get_major_formatter().labelOnlyBase = False
	# axs.set_yticks(np.arange(0, round(axs.get_ylim()[1]), 5))
	# print (caclocks_data, noncaclocks_data)

	# 画线程线
	# ylimit = round(axs.get_ylim()[1], -1)
	axs.axvline(hardthreads_line, alpha=0.618, linewidth=1)
	axs.axvline(bigthread_line,  alpha=0.618, linewidth=1, linestyle='dashed')

# 子图形式绘图
for bench in x86_benchname:
	fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(9, 3))
	draw_subfig_mop(x86_avg, bench, x86_threadlist, axs[0], x86_hardware_threads, x86_bigthread_line, txt_thread_nr, txt_mops)
	draw_subfig_mop(arm_avg, bench, arm_threadlist, axs[1], arm_hardware_threads, arm_bigthread_line, txt_thread_nr, "")
	plt.legend(loc='upper center', bbox_to_anchor=(-0.10, 1.25), frameon=False, labelspacing=0.1, columnspacing=1, handletextpad=0.2, ncol= len(use_libs)/2)
	matplotlib.pyplot.subplots_adjust(left=0.07, right = 0.998, bottom = 0.15, top = 0.87, wspace = 0.08 )
	plt.savefig("./fig/" + bench +".pdf", format = "pdf")
# show
plt.show()